﻿using CommandSystem;
using CommandSystem.Commands.RemoteAdmin.MutingAndIntercom;
using Exiled.API.Features;
using HarmonyLib;
using RemoteAdmin;
using RgCore.Database;
using RgCore.GameData;
using RgCore.Modules;
using RgCore.PlayerHud;
using System;
using System.Collections.Generic;
using System.Linq;
using VoiceChat;

namespace MuteRemastered
{
    public class IntercomUnmuteCommand_Remastered : CommandSystem.ICommand, IUsageProvider
    {
        public string Command => "iunmute";

        public string[] Aliases { get; }

        public string Description => "解除禁言玩家（广播室）";

        public string[] Usage => new string[] { "%player%" };

        public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
        {
            if (!sender.CheckPermission(new PlayerPermissions[] { PlayerPermissions.BanningUpToDay, PlayerPermissions.LongTermBanning, PlayerPermissions.PlayersManagement }))
            {
                response = "你没有足够的权限使用解除禁言！";
                return false;
            }
            response = "广播室解除禁言功能不再受支持，广播室禁言不再单独出现，请使用普通语音解禁功能";
            return false;
        }
    }
    public class IntercomMuteCommand_Remastered : CommandSystem.ICommand, IUsageProvider
    {
        public string Command => "imute";

        public string[] Aliases { get; }

        public string Description => "禁言玩家（广播室）";

        public string[] Usage => new string[] { "玩家ID/UserID", "时间(默认为分钟，可用h(时), d(天)结尾来改变单位)" };

        public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
        {
            if (!sender.CheckPermission(new PlayerPermissions[] { PlayerPermissions.BanningUpToDay, PlayerPermissions.LongTermBanning, PlayerPermissions.PlayersManagement }))
            {
                response = "你没有足够的权限使用禁言！";
                return false;
            }
            if (arguments.Count < 2)
            {
                response = "禁言系统已改良，面板操作无效！请使用指令禁言：imute <玩家ID/UserID> <时长>";
                return false;
            }
            Player player;
            if (int.TryParse(arguments.At(0), out int id))
            {
                player = Player.Get(id);
            }
            else
            {
                player = Player.Get(arguments.At(0));
            }
            var time = arguments.ElementAt(1);
            int multplier = 1;
            if (time.EndsWith("d"))
            {
                time = time.Remove(time.Length - 1);
                multplier = 1440;
            }
            else if (time.EndsWith("h"))
            {
                time = time.Remove(time.Length - 1);
                multplier = 60;
            }
            if (!int.TryParse(time, out int duration))
            {
                response = "提供了一个无效的时间！";
                return false;
            }
            duration *= multplier;
            MuteRemastered.AddMute(player?.UserId ?? arguments.At(0), duration, true);
            response = $"{(player == null ? $"离线玩家【{arguments.At(0)}】" : $"{player.Nickname}【{player.UserId}】")} 已被成功禁言{duration}分钟！";
            return true;
        }
    }
    public class UnmuteCommand_Remastered : CommandSystem.ICommand, IUsageProvider
    {
        public string Command => "unmute";

        public string[] Aliases { get; }

        public string Description => "解除禁言玩家（语音+广播室）";

        public string[] Usage => new string[] { "%player%" };

        public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
        {
            if (!sender.CheckPermission(new PlayerPermissions[] { PlayerPermissions.BanningUpToDay, PlayerPermissions.LongTermBanning, PlayerPermissions.PlayersManagement }))
            {
                response = "你没有足够的权限使用解除禁言！";
                return false;
            }
            Player player;
            if (int.TryParse(arguments.At(0).Remove(arguments.At(0).Length - 1), out int id))
            {
                player = Player.Get(id);
            }
            else
            {
                player = Player.Get(arguments.At(0));
            }
            MuteRemastered.RemoveMute(player?.UserId ?? arguments.At(0));
            response = $"{(player == null ? $"离线玩家【{arguments.At(0)}】" : $"{player.Nickname}【{player.UserId}】")} 已解除禁言！";
            return true;
        }
    }
    public class MuteCommand_Remastered : CommandSystem.ICommand, IUsageProvider
    {
        public string Command => "mute";

        public string[] Aliases { get; }

        public string Description => "禁言玩家（语音）";

        public string[] Usage => new string[] { "玩家ID/UserID", "时间(默认为分钟，可用h(时), d(天)结尾来改变单位)" };

        public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
        {
            if (!sender.CheckPermission(new PlayerPermissions[] { PlayerPermissions.BanningUpToDay, PlayerPermissions.LongTermBanning, PlayerPermissions.PlayersManagement }))
            {
                response = "你没有足够的权限使用禁言！";
                return false;
            }
            if (arguments.Count < 2)
            {
                response = "禁言系统已改良，面板操作无效！请使用指令禁言：mute <玩家ID/UserID> <时长>";
                return false;
            }
            Player player;
            if (int.TryParse(arguments.At(0), out int id))
            {
                player = Player.Get(id);
            }
            else
            {
                player = Player.Get(arguments.At(0));
            }
            var time = arguments.ElementAt(1);
            int multplier = 1;
            if (time.EndsWith("d"))
            {
                time = time.Remove(time.Length - 1);
                multplier = 1440;
            }
            else if (time.EndsWith("h"))
            {
                time = time.Remove(time.Length - 1);
                multplier = 60;
            }
            if (!int.TryParse(time, out int duration))
            {
                response = "提供了一个无效的时间！";
                return false;
            }
            duration *= multplier;
            MuteRemastered.AddMute(player?.UserId ?? arguments.At(0), duration, false);
            response = $"{(player == null ? $"离线玩家【{arguments.At(0)}】" : $"{player.Nickname}【{player.UserId}】")} 已被成功禁言{duration}分钟！\n";
            return true;
        }
    }
    public class MuteRemastered : RgPlugin
    {
        public override string Name => "禁言系统改良";

        public override string Id => "mute_remastered";
        public Harmony HarmonyPatch { get; set; }

        public override bool CanUnload => false;

        public override void OnDisabled()
        {
            if (DatabaseController.DatabaseDisabled)
            {
                return;
            }
            HarmonyPatch.UnpatchAll(Id);
            GameplayData.OnInitializedData -= GameplayData_OnInitializedData;
        }

        public override void OnEnabled()
        {
            if (DatabaseController.DatabaseDisabled)
            {
                Log.Warn("由于数据库未启用，此插件不加载");
                return;
            }
            HarmonyPatch = new Harmony(Id);
            HarmonyPatch.Patch(AccessTools.Method(typeof(VoiceChatMutes), nameof(VoiceChatMutes.LoadMutes)), 
                new HarmonyMethod(typeof(Patch).GetMethod(nameof(Patch.Prefix_LoadMutes))));
            GameplayData.OnInitializedData += GameplayData_OnInitializedData;
            CommandProcessor.RemoteAdminCommandHandler.UnregisterCommand(CommandProcessor.RemoteAdminCommandHandler.AllCommands.FirstOrDefault(x => x is MuteCommand));
            CommandProcessor.RemoteAdminCommandHandler.UnregisterCommand(CommandProcessor.RemoteAdminCommandHandler.AllCommands.FirstOrDefault(x => x is UnmuteCommand));
            CommandProcessor.RemoteAdminCommandHandler.UnregisterCommand(CommandProcessor.RemoteAdminCommandHandler.AllCommands.FirstOrDefault(x => x is IntercomMuteCommand));
            CommandProcessor.RemoteAdminCommandHandler.UnregisterCommand(CommandProcessor.RemoteAdminCommandHandler.AllCommands.FirstOrDefault(x => x is IntercomUnmuteCommand));
            CommandProcessor.RemoteAdminCommandHandler.RegisterCommand(new MuteCommand_Remastered());
            CommandProcessor.RemoteAdminCommandHandler.RegisterCommand(new UnmuteCommand_Remastered());
            CommandProcessor.RemoteAdminCommandHandler.RegisterCommand(new IntercomMuteCommand_Remastered());
            CommandProcessor.RemoteAdminCommandHandler.RegisterCommand(new IntercomUnmuteCommand_Remastered());
        }
        public static async void RemoveMute(string userid)
        {
            Player player = Player.Get(userid);
            var filter = new Dictionary<string, object>() { { "userid", userid } };
            if (player != null)
            {
                VoiceChatMutes.SetFlags(player.ReferenceHub, VcMuteFlags.None);
                player.SendFormattedMsg("mute", "<color=red>禁言</color>", "你的禁言已被管理员移除",
5, MsgType.Notification, ScreenLocation.CenterTop, false);
            }
            NoResponseCommandRequest cmd = new NoResponseCommandRequest("cdcp_mutes", RequestType.Delete, null, filter);
            await cmd.ProcessNonQuery();
        }
        public static async void AddMute(string userid, int minute, bool intercom)
        {
            Player player = Player.Get(userid);
            var filter = new Dictionary<string, object>() { { "userid", userid } };
            VcMuteFlags flag = intercom ? VcMuteFlags.LocalIntercom : VcMuteFlags.LocalRegular | VcMuteFlags.LocalIntercom;
            DateTime expires = DateTime.Now.AddMinutes(minute);
            Dictionary<string, object> data = new Dictionary<string, object>()
            {
                {"intercom_only", flag.HasFlag(VcMuteFlags.LocalRegular) ? 0 : 1 },
                { "issue_datetime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
                {"minutes", minute }
            };
            QueryCommandRequest req = new QueryCommandRequest("cdcp_mutes", filter, false, "issue_datetime", "minutes", "intercom_only");
            var list = (await req.GetResponseResult()).FirstOrDefault();
            if (list != null)
            {
                DateTime dt = DateTime.Parse(list["issue_datetime"].ToString());
                int minutes = int.Parse(list["minutes"].ToString());
                bool intercom_only = byte.Parse(list["intercom_only"].ToString()) == 1;
                VcMuteFlags origin_flag = intercom_only ? VcMuteFlags.LocalIntercom : VcMuteFlags.LocalRegular | VcMuteFlags.LocalIntercom;
                DateTime origin_expires = dt.AddMinutes(minutes);
                bool update_issuetime = expires > origin_expires;
                bool update_flag = flag > origin_flag;
                if (!update_flag)
                    data.Remove("intercom_only");
                else
                {
                    VoiceChatMutes.SetFlags(player.ReferenceHub, flag);
                    intercom_only = intercom;
                }
                if (!update_issuetime)
                {
                    data.Remove("minutes");
                    data.Remove("issue_datetime");
                }
                if (data.Count == 0)
                    return;
                NoResponseCommandRequest cmd = new NoResponseCommandRequest("cdcp_mutes", RequestType.Update, data, filter);
                await cmd.ProcessNonQuery();
                player?.SendFormattedMsg("mute", "<color=red>禁言</color>",
                    $"你被追加了一条持续至<color=yellow>{(update_issuetime ? expires.ToString("yyyy-MM-dd HH:mm:ss") : origin_expires.ToString("yyyy-MM-dd HH:mm:ss"))}</color>的<color=#00FFFF>{(intercom_only ? "广播室" : "语音")}</color>禁言，请规范游戏！",
                    10, MsgType.Notification, ScreenLocation.CenterTop, false);
                return;
            }
            VoiceChatMutes.SetFlags(player.ReferenceHub, flag);
            player?.SendFormattedMsg("mute", "<color=red>禁言</color>",
    $"你受到了持续至<color=yellow>{expires:yyyy-MM-dd HH:mm:ss}</color>的<color=#00FFFF>{(intercom ? "广播室" : "语音")}</color>禁言，请规范游戏！",
    10, MsgType.Notification, ScreenLocation.CenterTop, false);
            data.Add("userid", userid);
            NoResponseCommandRequest cmd2 = new NoResponseCommandRequest("cdcp_mutes", RequestType.Insert, data, null);
            await cmd2.ProcessNonQuery();
        }
        private async void GameplayData_OnInitializedData(Player player)
        {
            if (DatabaseController.DatabaseDisabled)
            {
                return;
            }
            var filter = new Dictionary<string, object>() { { "userid", player.UserId } };
            QueryCommandRequest req = new QueryCommandRequest("cdcp_mutes", filter, false, "issue_datetime", "minutes", "intercom_only");
            var list = (await req.GetResponseResult()).FirstOrDefault();
            if (list != null)
            {
                DateTime dt = DateTime.Parse(list["issue_datetime"].ToString());
                int minutes = int.Parse(list["minutes"].ToString());
                bool intercom_only = byte.Parse(list["intercom_only"].ToString()) == 1;
                VcMuteFlags flag = intercom_only ? VcMuteFlags.LocalIntercom : VcMuteFlags.LocalRegular | VcMuteFlags.LocalIntercom;
                DateTime expires = dt.AddMinutes(minutes);
                if (expires < DateTime.Now)
                {
                    NoResponseCommandRequest cmd = new NoResponseCommandRequest("cdcp_mutes", RequestType.Delete, null, filter);
                    await cmd.ProcessNonQuery();
                    return;
                }
                VoiceChatMutes.SetFlags(player.ReferenceHub, flag);
                player.SendFormattedMsg("mute", "<color=red>禁言</color>", 
                    $"你有一项截至<color=yellow>{expires:yyyy-MM-dd HH:mm:ss}</color>的<color=#00FFFF>{(intercom_only ? "广播室" : "语音")}</color>禁言，请规范游戏！", 
                    10, MsgType.Message, ScreenLocation.CenterTop, false);
            }
        }
    }
    public static class Patch
    {
        public static bool Prefix_LoadMutes()
        {
            VoiceChatMutes._everLoaded = true;
            return false;
        }
    }
}
